﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;

// 人形角色控制
public class HumanCtrl : MonoBehaviour
{

    // 默认移动速度（初始速度）
    public float DefaultMoveSpeed = 2.5f;
    // 基础移动速度(没有加速效果的速度),基础速度会随着奔跑距离而提升
    private float _baseMoveSpeed;
    public float BaseMoveSpeed
    {
        get { return _baseMoveSpeed; }
        private set
        {
            _baseMoveSpeed = value;
            FollowUpSpeed = _baseMoveSpeed * 2;
        }
    }
    // 追击速度
    public float FollowUpSpeed { get; private set; }
    // 默认跳跃速度
    public float DefaultJumpSpeed = 10;
    // 滑翔降落速度
    public float GlidingFallSpeed = -1;
    // 默认重力倍数
    public float DefaultGravity = 3;
    // 踩怪反弹速度
    public float DefaultAttackOverSpeed = 7;
    // 最大多段跳次数
    public int MulJumpCount = 2;
    // 飞行高度
    public float FlyHigh = 1.5f;

    // 正常移动时，距摄像机的距离
    public float DefaultDisByCamera = 3;

    // 超过这个距离，开始追
    public float MaxFollowUpDis = 0.1f;

    // 移动速度
    public float MoveSpeed
    {
        set { _rig.velocity = new Vector2(value, _rig.velocity.y); }
        get { return _rig.velocity.x; }
    }
    // 当前跳跃速度
    public float JumpSpeed
    {
        set { _rig.velocity = new Vector2(_rig.velocity.x, value); }
        get { return _rig.velocity.y; }
    }

    // 是否在下落(由于受重力影响，速度为0，即将下落)
    public bool IsFallingDown { get { return JumpSpeed < 0 || Utils.FloatEqual(JumpSpeed, 0); } }
    
    Transform _groundCheck;
    Transform _topCheck;
    private float _checkRadius = 0.1f; // 检测地面时的检测范围

    public Transform EffectRoot { get; internal set; }

    // 被怪物杀死，回调
    private Action _beKilledCallback;

    Animator _ani;
    //Animation _anim;
    PlayerSkillMgr _skillMgr = new PlayerSkillMgr();
    SceneCamera _mainCamera;

    Rigidbody2D _rig;
    BoxCollider2D _collider;
    Vector2 _defaultColliderSize;
    Vector2 _defaultColliderOffset;

    AudioSource _audio;

    Transform _cameraTransform;

    HumanStateMgr _stateMgr = new HumanStateMgr();

    TimerMgr.Timer _logicTimer;

    internal void Init(SceneCamera mainCamera, Action beKilledCallback)
    {
        _mainCamera = mainCamera;
        _beKilledCallback = beKilledCallback;
        _skillMgr.Init(this);

        FightUIMgr.Instance.SetBtn(obj => onDownKeyDown(),
            obj => onDownKeyUp(),
            obj => onJumpKeyDown(),
            obj => onJumpKeyUp());

        _ani = GetComponent<Animator>();
        _rig = GetComponent<Rigidbody2D>();
        _collider = GetComponent<BoxCollider2D>();
        _defaultColliderSize = _collider.size;
        _defaultColliderOffset = _collider.offset;

        _groundCheck = transform.Find("GroundCheck");
        _topCheck = transform.Find("TopCheck");
        EffectRoot = transform.Find("Effect");
        _cameraTransform = _mainCamera.transform;
        DefaultDisByCamera = Mathf.Abs(_cameraTransform.position.x - transform.position.x);

        _audio = gameObject.AddComponent<AudioSource>();
        _audio.playOnAwake = false;

        BaseMoveSpeed = DefaultMoveSpeed;

        // 状态控制要等所有数据初始化完毕后才开始
        _stateMgr.Init(this, _beKilledCallback);

        _rig.gravityScale = 0;

        _logicTimer = TimerMgr.Instance.CreateTimer(0, -1, logicLoop);
    }

    // 不能用Start，Unity关键字。。。。。。。
    public void Begin()
    {
        setMoveSpeed(BaseMoveSpeed);
        _logicTimer.Start();
        _stateMgr.Start();
        ResetGravity();
    }

    public void Release()
    {
        _stateMgr.Release();
        _logicTimer.Stop();
    }
    // 设置滑翔v轴速度
    internal void SetVSpeedForGliding()
    {
        JumpSpeed = GlidingFallSpeed;
        _rig.gravityScale = 0;
    }

    public void ResetGravity()
    {
        _rig.gravityScale = DefaultGravity;
    }

    // 跳一次
    internal void JumpOnce(RoleState sType, float jumpSpeed = -1)
    {
        if (jumpSpeed < 0) { jumpSpeed = DefaultJumpSpeed; }
        JumpSpeed = jumpSpeed;

        PlayAni(sType);
    }

    // 设置滑铲的碰撞区域
    internal void SetDownCollider()
    {
        _collider.size = new Vector2(_collider.size.x, _defaultColliderSize.y * 0.5f);
        _collider.offset = _defaultColliderOffset - new Vector2(0, _collider.size.y * 0.5f);
    }

    // 重置碰撞区域
    internal void ResetCollider()
    {
        _collider.offset = _defaultColliderOffset;
        _collider.size = _defaultColliderSize;
    }

    // 播放动画
    public void PlayAni(RoleState ani)
    {
        //Debug.LogWarning("ani " + ani);
        //Debug.Log(_stateMgr.CurState);
        _ani.SetTrigger(ani.ToString());
    }

    private void onJumpKeyUp() { _stateMgr.OnJumpKeyUp(); }
    private void onJumpKeyDown() { _stateMgr.OnJumpKeyDown(); }
    private void onDownKeyUp() { _stateMgr.OnDownKeyUp(); }
    private void onDownKeyDown() { _stateMgr.OnDownKeyDown(); }


    private void inputLoop()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            onJumpKeyDown();
        }
        if (Input.GetKeyUp(KeyCode.Space))
        {
            onJumpKeyUp();
        }

        if (Input.GetKeyDown(KeyCode.S))
        {
            onDownKeyDown();
        }
        if (Input.GetKeyUp(KeyCode.S))
        {
            onDownKeyUp();
        }
    }

    public bool CheckPlayerBottomState()
    {
        var isGround = false;

        // The player is grounded if a circlecast to the groundcheck position hits anything designated as ground
        Collider2D[] colliders = Physics2D.OverlapCircleAll(_groundCheck.position, _checkRadius, 1 << LayerMask.NameToLayer("Ground"));
        for (int i = 0; i < colliders.Length; i++)
        {
            if (colliders[i].gameObject != gameObject)
                isGround = true;
        }

        return isGround;
    }

    // 头顶的状态(滑铲过程中能否站直)
    public bool CheckPlayerTopState()
    {
        var isTopHit = false;

        // The player is grounded if a circlecast to the groundcheck position hits anything designated as ground
        Collider2D[] colliders = Physics2D.OverlapCircleAll(_topCheck.position, _checkRadius, 1 << LayerMask.NameToLayer("Block"));
        for (int i = 0; i < colliders.Length; i++)
        {
            if (colliders[i].gameObject != gameObject)
            {
                isTopHit = true;
            }
        }
        //Debug.Log(isTopHit + "," + Time.frameCount);
        return isTopHit;
    }

    // 吃金币
    private void eatCoin(Coin coin)
    {
        coin.BeEat(this);
    }


    private void eatItem(Item item)
    {
        AddSkill(item.ID);
        item.BeEat(this);
    }
    // 技能
    public void AddSkill(int id)
    {
        _skillMgr.AddSkill(id);
    }

    private void Update()
    {
        inputLoop();
    }

    private void logicLoop()
    {
        autoFollowUp();
    }

    // 飞行状态
    public void SetFlyState(bool bFly, float speedUpValue = -1)
    {
        _stateMgr.OnFly(bFly, speedUpValue);
    }

    internal void SetFlySpeed(bool bFly, float speedUpValue = -1)
    {
        if (bFly)
        {
            // 提升到飞行高度
            transform.position = new Vector3(transform.position.x, FlyHigh, transform.position.y);
            JumpSpeed = 0;

            _rig.gravityScale = 0;
            _collider.isTrigger = true; // 防止异常碰撞
            setMoveSpeed(speedUpValue);
        }
        else
        {
            _rig.gravityScale = DefaultGravity;
            _collider.isTrigger = false; // 防止异常碰撞
            setMoveSpeed(BaseMoveSpeed);
        }
    }

    // 整体加速
    internal void SpeedUp(float newSpeed)
    {
        var oldBaseSpeed = BaseMoveSpeed;
        BaseMoveSpeed = newSpeed;
        //Debug.Log(string.Format("set speed {0}, oldBaseSpeed {1}, MoveSpeed {2}", BaseMoveSpeed, oldBaseSpeed, MoveSpeed));
        // 提速时处于正常移动状态，才改变速度。否则等速度还原时自动改变
        if (Utils.FloatEqual(MoveSpeed, oldBaseSpeed))
        {
            setMoveSpeed(BaseMoveSpeed);
        }
    }
    // 设置整体(角色、相机)移动速度
    private void setMoveSpeed(float speed)
    {
        MoveSpeed = speed;
        //Debug.Log(string.Format("speed = {0}, MoveSpeed = {1}", speed, MoveSpeed));
        _mainCamera.Speed = speed;
    }


    private void autoFollowUp()
    {
        var dis = _cameraTransform.position.x - transform.position.x;
        if (dis > MaxFollowUpDis + DefaultDisByCamera) // 追赶
        {
            MoveSpeed = FollowUpSpeed;
        }
        // 追上
        if (dis <= DefaultDisByCamera)
        {
            MoveSpeed = _mainCamera.Speed;
            transform.position = new Vector3(_cameraTransform.position.x - DefaultDisByCamera, transform.position.y, transform.position.z);
        }
    }
    private void OnCollisionEnter2D(Collision2D other)
    {
        // 仅对阻挡做处理
        if (other.gameObject.layer != LayerMask.NameToLayer("Block")) { return; }

        _skillMgr.OnBolckEnter(other.transform);
    }

    private void OnTriggerEnter2D(Collider2D other)
    {
        // 友好道具(技能、金币)
        if (other.gameObject.layer == LayerMask.NameToLayer("Friend"))
        {
            var coin = other.GetComponent<Coin>();
            if (coin != null)
            {
                eatCoin(coin);
                return;
            }

            var item = other.GetComponent<Item>();
            if (item != null)
            {
                eatItem(item);
                return;
            }

            return;
        }

        if (other.gameObject.layer == LayerMask.NameToLayer("Enemy"))
        {
            var enemy = other.GetComponent<Enemy>();
            if (_skillMgr.OnEnemyEnter(enemy))
            {
                // 敌人被技能杀死
                return;
            }

            _stateMgr.OnEnemyEnter(enemy);
            return;
        }
    }
}
